先简单汇总一些本部分的内容:

内置高阶组件 作用 配置项
configureStore 封装版的 createStore(简化配置) reducer、middleware、devTools
createSlice 在原 reducer 拆分思想不变的情况下将单个模块汇于一个文件(减少模板文件) name、initialState、reducers、extraReducers
createAsyncThunk 用于解决 RTK 中单个模块的异步任务(内置 redux-thunk 包)

# 1、基本介绍

  Redux Toolkit 是 Redux 官方推荐的编写 Redux 逻辑的标准方法。用于解决:

  • 配置 Redux 存储太复杂
  • Redux 需要太多样板代码
  • 必须添加很多包才能让 Redux 做任何有用的事情

  Redux Toolkit 包括强大的数据获取和缓存功能,我们称之为“RTK 查询”。因此,在很多地方,我们将 Redux Toolkit 简称为 RTK。

# 2、安装使用

npm install @reduxjs/toolkit react-redux

  前面我们已经学到了 react-redux 有 Provideconnect()、 等高阶组件用于将 react 和 redux 关联

  下面我们将利用 RTK 中的 configureStorecreateSlicecreateAsyncThunk 等 API 来简化原 redux 高级 API 使用时的代码模板

RTK 快速入门:Usage Guide (opens new window)

# 3、configureStore

  configureStore 对 createStore 进行了包装,其提供了简化的配置选项并提供了良好的默认值:

在 RTK 中,redux-thunk 默认使用,并且默认开启了 redux-devtools

原来 redux 的实现方式

  使用的是 redux 中的 applyMiddleware 和 compose

import { createStore, applyMiddleware, compose } from 'redux'
import thunk from 'react-thunk'

import reducer from './reducer.js'

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
export default createStore(reducer, composeEnhancers(applyMiddleware(thunk)))

  configureStore 函数接收一个对象,其对象中包含 reducer、middleware、devTools 三大选项

// @/store/index.js
import { configureStore } from '@reduxjs/toolkit'

import cartReducer from './features/cart.js'

export default configureStore({
  reducer: {
    cart: cartReducer
  }
})

# 4、createSlice ✨

  createSlice 可以简化以前使用 redux 的 combineReducers 的模块化方案

├── store
    ├── index.js
    └── featres
        ├── cart.js
        └── products.js

  createSlice 函数接收一个对象,其对象中包含 name、initialState、reducers 三大选项

// features/cart.js
import { createSlice } from '@reduxjs/toolkit'

const cartSlice = createSlice({
  name: 'cart',
  initialState: {
    counter: 1
  },
  reducers: {
    countChangeAction(state, action) {
      // 传递参数的默认选项为 payload
      state.counter = eval(state.counter + action.payload) // RTK 底层使用了immerjs库来保证的数据不可变性(immutablejs也可以实现相同的功能)
    }
  }
})

export const { countChangeAction } = cartSlice.actions

export default cartSlice.reducer
使用示例
import { connect } from 'react-redux'

// 仅仅这里不一样而已😂
import { countChangeAction } from '@/store/features/cart.js'

class Left extends React.PureComponent {
  upDownHandle(str) {
    this.props.countChange(str)
  }

  render() {
    const { count } = this.props

    return (
      <div>
        <p>left couter: {count}</p>
        <button onClick={(e) => this.upDownHandle('+1')}>+1</button>
        <button onClick={(e) => this.upDownHandle('+3')}>+3</button>
      </div>
    )
  }
}

// ==============

const mapStateToProps = (state) => ({
  count: state.cart.counter
})

const mapDispatchToProps = (dispatch) => ({
  countChange: function (str) {
    dispatch(countChangeAction(str))
  }
})

export default connect(mapStateToProps, mapDispatchToProps)(Demo)

# 5、createAsyncThunk

  createAsyncThunk 可以简化以前使用 redux 的 applyMiddleware 添加 redux-thunk 来增强原 redux 功能,可以实现异步请求相同的功能

promise 的三种状态:pending、fulfilled、rejected

// features/cart.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'

// 创建一个action 并导出
export const getListDataAction = createAsyncThunk('getListData', async (payload, extraInfo) => {
  const res = await axios.get('/data.json')
  return res.data
})

const cartSlice = createSlice({
  name: 'cart',
  initialState: {
    dataList: []
  },
  reducers: {},

  // 方式1(动态函数名)
  extraReducers: {
    [getListDataAction.fulfilled](state, action) {
      state.dataList = action.payload
    }
  }

  // 方式2(链式调用)
  extraReducers: (builder) => {
    builder.addCase(getListDataAction.fulfilled, (state, action) => {
      state.dataList = action.payload
    })
  }
})

export default cartSlice.reducer
更新于 : 8/7/2024, 2:16:31 PM